package com.yokead.controller.digging;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.CharsetUtil;
import cn.jiangzeyin.Md5Util;
import cn.jiangzeyin.StringUtil;
import cn.jiangzeyin.common.JsonMessage;
import com.yokead.common.Config;
import com.yokead.common.EncodeFileUtil;
import com.yokead.common.QiNiuFile;
import com.yokead.common.QiNiuUtil;
import com.yokead.common.base.DiggingBaseControl;
import com.yokead.system.log.LogType;
import com.yokead.system.log.SystemLog;
import com.yokead.util.EncryptUtil;
import com.yokead.util.UrlDecode;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

/**
 * Created by jiangzeyin on 2017/6/28.
 */
@Controller
@RequestMapping("digging")
public class DiggingControl extends DiggingBaseControl {

    @RequestMapping(value = "index.html", produces = MediaType.TEXT_HTML_VALUE)
    public String index() {
        return "digging/index";
    }

    @RequestMapping(value = "bank_to.html", produces = MediaType.TEXT_HTML_VALUE)
    public String bank_to(String tag, String status) throws UnsupportedEncodingException {
        String result = checkTag(tag, status);
        if (result != null) {
            return result;
        }
        setAttribute("tag", tag);
        setAttribute("status", status);
        return "digging/edit_1";
    }

    private String checkTag(String tag, String status) throws UnsupportedEncodingException {
        if (!StringUtil.isEmpty(status)) {
            if (!"tf".equals(status) && !"sh".equals(status)) {
                return dore("status 不正确", tag, status);
            }
        }
        if (!StringUtil.isEmpty(tag)) {
            try {
                String path = EncryptUtil.decrypt(tag);
                File file = new File(path);
                if (!file.exists()) {
                    return dore("tag 不正确", tag, status);
                }
                if ("tf".equals(status)) {
                    File tf = new File(file.getParentFile(), "index_tf.html");
                    if (tf.exists()) {
                        return dore("已经存在投放页啦", tag, status);
                    }
                } else if ("sh".equals(status)) {
                    File sh = new File(file.getParentFile(), "index_sh.html");
                    if (sh.exists()) {
                        return dore("已经存在审核页啦", tag, status);
                    }
                }
            } catch (Exception e) {
                SystemLog.LOG(LogType.CONTROL_ERROR).error("判断tag", e);
                return dore("tag 异常" + e.getMessage(), tag, status);
            }
        }
        return null;
    }


    @RequestMapping(value = "do", method = RequestMethod.POST, produces = MediaType.TEXT_HTML_VALUE)
    public String doUrl(String url,
                        boolean weixin,
                        boolean js,
                        boolean tongji, String tag, String status,
                        boolean h404, String quality, boolean ys) throws UnsupportedEncodingException {
        float quality_ = StringUtil.parseFloat(quality);
        if (quality_ == 0.0F) {
            quality_ = 0.7f;
        } else if ((quality_ != 100.0F) && (quality_ <= 0.0F || quality_ >= 1.0F)) {
            quality_ = 0.7f;
        }
        if (!ys) {
            quality_ = 100.0F;
        }
        if (StringUtil.isEmpty(url)) {
            return dore("请输入链接", tag, status);
        }
        String result = checkTag(tag, status);
        if (result != null) {
            return result;
        }
        File tempParent = new File(String.format("%s/temp/%s", Config.Admin.getTempDir(), userName));
        if (!FileUtil.clean(tempParent)) {
            SystemLog.LOG().info("清理临时文件失败：" + tempParent.getPath());
        }
        try {
            Connection connection = Jsoup.connect(url);
            Document document = connection.timeout(10 * 1000).userAgent(UAG).get();
            String doMain = QiNiuUtil.getDoMain();
            {
                // 处理编码
                Elements metas = document.getElementsByTag("meta");
                metas.forEach(element -> {
                    String httpEquiv = element.attr("http-equiv");
                    if ("Content-Type".equalsIgnoreCase(httpEquiv)) {
                        element.attr("content", "text/html; charset=utf-8");
                    }
                });
                Elements scripts = document.getElementsByTag("script");
                if (js) {
                    scripts.remove();
                } else {
                    // 下载js
                    scripts.forEach(element -> {
                        String src = element.attr("src").trim();
                        if (!StringUtil.isEmpty(src)) {
                            if (tongji) { // 判断统计代码
                                if (src.contains("cnzz.com")) {
                                    element.remove();
                                }
                            }
                            String jsUrl = convertUrl(src, url);
                            String mName;
                            try {
                                mName = Md5Util.getString(jsUrl);
                            } catch (NoSuchAlgorithmException e) {
                                throw new RuntimeException(e);
                            }
                            String fileName = String.format("%s/js/%s.js", tempParent.getPath(), mName);
                            boolean flag;
                            try {
                                flag = httpDownload(jsUrl, fileName, h404);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                            // 清理404 标签
                            if (!flag && h404) {
                                element.remove();
                                return;
                            }
                            if (!flag) {
                                throw new RuntimeException("下载文件失败：" + jsUrl);
                            }
                            // 强制为utf-8
                            try {
                                fileName = EncodeFileUtil.convert(new File(fileName), "UTF-8");
                            } catch (IOException e) {
                                SystemLog.LOG(LogType.CONTROL_ERROR).error("转换文件编码失败：" + fileName, e);
                                throw new RuntimeException("转换文件编码失败" + e.getMessage());
                            }
                            String md5;
                            try {
                                md5 = QiNiuFile.doUploadFile(fileName);
                            } catch (Exception e) {
                                SystemLog.LOG(LogType.CONTROL_ERROR).error("扒取失败：" + jsUrl, e);
                                throw new RuntimeException(e.getMessage());
                            }
                            src = StringUtil.clearPath(String.format("%s/%s", doMain, md5));
                            element.attr("src", src);
                        }
                    });
                }
            }
            {
                Elements link = document.getElementsByTag("link");
                link.forEach(element -> {
                    String rel = element.attr("rel");
                    if (!StringUtil.isEmpty(rel) && !"stylesheet".equalsIgnoreCase(rel)) {
                        return;
                    }
                    String href = element.attr("href").trim();
                    String hrefUrl = convertUrl(href, url);
                    String mName;
                    try {
                        mName = Md5Util.getString(hrefUrl);
                    } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException(e);
                    }
                    String fileName = String.format("%s/css/%s.css", tempParent.getPath(), mName);
                    boolean flag;
                    try {
                        flag = httpDownload(hrefUrl, fileName, h404);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    // 清理404 标签
                    if (!flag && h404) {
                        element.remove();
                        return;
                    }
                    if (!flag) {
                        throw new RuntimeException("下载文件失败：" + hrefUrl);
                    }
                    String md5;
                    try {
                        md5 = QiNiuFile.doUploadFile(fileName);
                    } catch (Exception e) {
                        SystemLog.LOG(LogType.CONTROL_ERROR).error("扒取失败" + hrefUrl, e);
                        throw new RuntimeException(e.getMessage());
                    }
                    href = StringUtil.clearPath(String.format("%s/%s", doMain, md5));
                    element.attr("href", href);
                });
            }
            {
                Elements imgs = document.getElementsByTag("img");
                float finalQuality_ = quality_;
                imgs.forEach(element -> {
                    String src;
                    String attrName = weixin ? "data-src" : "src";
                    src = element.attr(attrName).trim();
                    if (weixin) {
                        element.removeAttr("data-src");
                    }
                    if (StringUtil.isEmpty(src)) {
                        return;
                    }
                    String srcUrl = convertUrl(src, url);
                    String mName = null;
                    try {
                        mName = Md5Util.getString(srcUrl);
                    } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException(e);
                    }
                    String fileName = String.format("%s/img/%s", tempParent.getPath(), mName);
                    boolean flag;
                    try {
                        flag = httpDownload(srcUrl, fileName, h404);
                    } catch (Exception e) {
                        SystemLog.LOG(LogType.CONTROL_ERROR).error("扒取失败", e);
                        throw new RuntimeException(e);
                    }
                    // 清理404 标签
                    if (!flag && h404) {
                        element.remove();
                        return;
                    }
                    if (!flag) {
                        throw new RuntimeException("下载文件失败：" + srcUrl);
                    }
                    String md5;
                    try {
                        md5 = QiNiuFile.doUploadFile(fileName, finalQuality_);
                    } catch (Exception e) {
                        SystemLog.LOG(LogType.CONTROL_ERROR).error("扒取失败:" + srcUrl, e);
                        throw new RuntimeException(e.getMessage());
                    }
                    // String trueName = getTrueName(mName);
                    src = StringUtil.clearPath(String.format("%s/%s", doMain, md5));
                    element.attr("src", src);
                });
            }
            String time = String.valueOf(System.currentTimeMillis());
            FileUtil.writeString(document.toString(), String.format("%s/html/%s.html", tempParent.getPath(), time), CharsetUtil.CHARSET_UTF_8);
            setAttribute("time", time);
            setAttribute("tag", tag);
            setAttribute("status", status);
            return "digging/edit_1";
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("扒取失败：" + url, e);
            return dore("获取异常:" + e.getMessage(), tag, status);
        }
    }

    private String dore(String tip, String tag, String status) throws UnsupportedEncodingException {
        String url = "redirect:index.html?tip=" + UrlDecode.getURLEncode(tip);
        if (!StringUtil.isEmpty(tag)) {
            url += "&tag=" + tag;
        }
        if (!StringUtil.isEmpty(status)) {
            url += "&status=" + status;
        }
        return url;
    }

    @RequestMapping(value = "getContext.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String save_weixin(String time) {
        time = convertFilePath(time);
        File tempParent = new File(String.format("%s/temp/%s", Config.Admin.getTempDir(), userName));
        try {
            File file = new File(String.format("%s/html/%s.html", tempParent.getPath(), time));
            if (!file.exists()) {
                return JsonMessage.getString(400, "获取失败");
            }
            String context = FileUtil.readString(file, CharsetUtil.CHARSET_UTF_8);
            if (!file.delete()) {
                SystemLog.LOG().info("删除文件失败：" + file.getPath());
            }
            return JsonMessage.getString(200, "", context);
        } catch (IORuntimeException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("获取内容异常", e);
            return JsonMessage.getString(500, "获取异常：" + e.getMessage());
        }
    }
}
